package org.invigorare.auctions.data.entities;

import static org.invigorare.auctions.data.SaleDataOpener.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.invigorare.MapUtils;
import org.invigorare.auctions.data.SynchronizableDataOpener;
/**
 * A class containing data corresponding to 
 * one row of the License_table, and related helper methods.
 */
public class AuctionSale {
	
	public static final String WEB_SALE_EMPLOYEE = "employee";
	public static final String WEB_SALE_TIME = "sold";
	public static final String WEB_SALE_ENTRY_ID = "entry_id";
	public static final String WEB_SALE_TOLL_NO = "toll";
	public static final String WEB_SALE_SELLER_LIC = "seller_license";
	public static final String WEB_SALE_BUYER_LIC = "buyer_license";
	public static final String WEB_SALE_PROD_ID = "produce_id";
	public static final String WEB_SALE_WEIGHT = "weight";
	public static final String WEB_SALE_RATE = "rate";

	public static final String _OUTBOUND_NOT_SUPPORTED_ = "";
	
	public static final String[] WEB_KEYS = new String[] {
		WEB_SALE_EMPLOYEE,
		WEB_SALE_TIME,
		WEB_SALE_ENTRY_ID,
		WEB_SALE_TOLL_NO,
		WEB_SALE_SELLER_LIC,
		WEB_SALE_BUYER_LIC,
		WEB_SALE_PROD_ID,
		WEB_SALE_WEIGHT,
		WEB_SALE_RATE
	};

	private static String[] DB_KEYS;
	public static String[] DB_KEYS() {
		setupColumnTranslations();
		return DB_KEYS;
	}
	
	/* Internal storage of fields: keyed by db column names */
	// everything is converted to Strings, which is what gets transmitted over HTTP POST.
	private Map<String, String> map;

	/* Translate column names */
	private static Map<String, String> dbToWeb, webToDb;
	
	private static void setupColumnTranslations() {
		if (dbToWeb == null) {
			dbToWeb = new HashMap<String, String>();
			dbToWeb.put(EMPLOYEE_NO, WEB_SALE_EMPLOYEE);
			dbToWeb.put(ENTRY_ID, WEB_SALE_ENTRY_ID);
			dbToWeb.put(TOLLRECEIPT_NO, WEB_SALE_TOLL_NO);
			dbToWeb.put(SALE_TIMESTAMP, WEB_SALE_TIME);
			dbToWeb.put(SELLER_LICENSE, WEB_SALE_SELLER_LIC);
			dbToWeb.put(BUYER_LICENSE, WEB_SALE_BUYER_LIC);
			dbToWeb.put(SALE_PRODUCE_ID, WEB_SALE_PROD_ID);
			dbToWeb.put(SALE_WEIGHT, WEB_SALE_WEIGHT);
			dbToWeb.put(SALE_RATE, WEB_SALE_RATE);
			
			/* In general, we don't get needless fields from the DB to save some time.
			 * By not including those needless fields (unsupported or not needed by the webserver),
			 * we can simply use the keySet of dbToWeb as the list of DB columns to fetch.
			 */
			dbToWeb.put(MARKET_NAME, _OUTBOUND_NOT_SUPPORTED_);
			/*dbToWeb.put(SALE_TOTAL, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_UNLOAD, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_CLEAN, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_WEIGH, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_LOAD, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_PACK, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(FEE_STITCH, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(COMMISSION_AGENT, _OUTBOUND_NOT_SUPPORTED_);
			dbToWeb.put(COMMISSION_MANDI, _OUTBOUND_NOT_SUPPORTED_);*/
		}
		
		if (webToDb == null) {
			webToDb = new MapUtils<String, String>().invertedMap(dbToWeb);
		}
		
		if (DB_KEYS == null) {
			List<String> mapped = new MapUtils<String, String>().mapAll(webToDb, WEB_KEYS);
			DB_KEYS = mapped.toArray(new String[mapped.size()]);
		}
	}

	public AuctionSale() {
		setupColumnTranslations();
		map = new HashMap<String, String>();
		//map.put(ENTRY_ID, "1.1305843740"); // TODO: STOP HARDCODING ENTRY_ID. download the DB
	}
	
	int rowId;
	
	public AuctionSale(Map<String, Object> map_dbEntry) {
		this();
		
		Set<Entry<String,Object>> entrySet = map_dbEntry.entrySet();
		for (Entry<String, Object> pair : entrySet ) {
			if (pair.getKey().equals(SynchronizableDataOpener._ROW_ID_)) {
				// this is the only Value that should not be a String (local to app, used to update database metadata)
				this.rowId = (Integer) pair.getValue();
			}
			if (pair.getValue() instanceof String) {
				put_dbKey(pair.getKey(), (String) pair.getValue());
			}
		}
	}
	
	public int getRowId() {
		return rowId;
	}
	
	public void put_dbKey(String dbKey, String value) {
		if (dbKey.equals(SALE_TIMESTAMP)) 
			value = String.valueOf(System.currentTimeMillis() / 1000L - 100); // TODO: legitimately convert to unix time;
		map.put(dbKey, value);
	}
	
	public void put_webKey(String webKey, String value) {
		String dbKey = webToDb.get(webKey);
		put_dbKey(dbKey, value);
	}
	
	public String get_dbKey(String dbKey) {
		return map.get(dbKey);
	}
	
	public String get_webKey(String webKey) {
		String dbKey = webToDb.get(webKey);
		return get_dbKey(dbKey);
	}
	
	public String toString() {
		StringBuilder sb = new StringBuilder();
		
		sb.append("{\nAuction between ");
		sb.append("Seller ID ");
		sb.append(get_dbKey(SELLER_LICENSE));
		sb.append(" and Buyer ID ");
		sb.append(get_dbKey(BUYER_LICENSE));
		sb.append("\n");
		
		sb.append("For produceId:");
		String prodId = get_dbKey(SALE_PRODUCE_ID);
		sb.append(prodId);
		
		sb.append(" quantity:");
		sb.append(get_dbKey(SALE_WEIGHT));
		sb.append(" price-per-qty:");
		sb.append(get_dbKey(SALE_RATE));
		sb.append("\n");
		
		//sb.append("At Market: ");
		//sb.append(get_dbKey(MARKET_NAME));
		sb.append(" by employeeId:");
		sb.append(get_dbKey(EMPLOYEE_NO));
		sb.append(" entryNo:");
		sb.append(get_dbKey(ENTRY_ID));
		sb.append(" at timestamp:");
		sb.append(get_dbKey(SALE_TIMESTAMP));
		sb.append("\n}");
		
		return sb.toString();
	}
	
}
